看一下簡短的模型範例:
from tensorflow.keras.models import Sequential
from tensorflow.keras import layers
#建構模型
model = Sequential([
layers.Dense(512, activation="relu")
])
#編譯模型
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
model.build(input_shape=(None, 784))
model.add(layers.Dense(10, activation="softmax"))
model.add(layers.Dense(20, activation="relu"))
由上程式,表示出 model sequence 可以包著許多層 layer。
觀察 Sequence Model 在起一個實例時運作了什麼。下圖是起一個模型實例的示意簡圖:
Sequence 類別圖如下:
從類別圖會發現,keras.engine.training.Model 也繼承 keras.engine.base_layer.Layer,Model 也可以說是Layer的一種。
針對範例程式,輸入的layer為keras.layers.core.dense物件實體,針對這種輸入keras.engine.sequential 類別會做那些主要的事。(其它種類的layer也會有對應的範例)
首先會到 keras.engine.sequential 類別的父類別 keras.engine.training.Model 執行建構子方法__new__,
再透過 keras.engine.training.Model 父類別 keras.engine.base_layer.Layer 的建構子方法__new__。
此建構子主要會把 keras.engine.sequential 類別的 init 方法的參數名稱取出:
['layers'、'name']
將這些參數對應實際所傳的值組成dictionary,更新到**kwargs中,供後續初始化程式使用。
當keras.engine.sequential 的 instance建立起來後,就開始執行keras.engine.base_layer.Layer 的 __init__函式,做初始設定一些屬性,比較重要的是呼叫 keras.engine.base_layer.Layer._init_call_fn_args():
透過keras.utils.tf_inspect.getfullargspec函式,將keras.engine.sequential.call 函數的參數取出包到 FullArgSpec 物件中,然後再傳入keras.utils.layer_utils.CallFunctionSpec類別建構子,設定
(a) keras.engine.sequential._full_argspec 為 FullArgSpec 物件
(b) keras.engine.sequential._arg_names 為 [ 'inputs', 'training', 'mask']
(c) 因為有 'training' 與 'mask'參數名,所以
keras.engine.sequential._expects_training_arg = True
keras.engine.sequential._expects_mask_arg = True
到此大致上是在敘述,會對參數做初始設定的動作。
接著執行 keras.engine.training.Model 的 __init__函式,此函式也初始化許多內部屬性,於此省略敘述。
接下來主要動作是,將keras.engine.sequential建構子參數layers中所指定的值設定到keras.engine.sequential 實體物件之中(註: Adds a layer instance on top of the "layer stack".),以透過 keras.engine.sequential.add 方法:
(1)
強制設定 keras.engine.training.Model.built 為false,代表有層的加入需要重新建構模型的意思。
(2)
檢查是否為 keras.engine.base_layer.Layer 的實體物件,如果不是則嘗試使用keras.engine.functional.ModuleWrapper類別將傳入的模組
融入keras.engine.base_layer.Layer所產生的實體。
(3)
檢查keras.engine.sequential物件實體是否有_self_tracked_trackables屬性(type 為list),如果無則新增屬性並設定為空的list。
(4)
將傳入的 layer物件逐一加入到 keras.engine.sequential._self_tracked_trackables 與keras.engine.training.Model.layers中。
(5)
利用tf_inspect.getfullargspec函式(透過inspect.getfullargspec(https://docs.python.org/zh-tw/3/library/inspect.html))將 keras.layers.core.dense 物件中的 call 方法參數等資訊存入 keras.engine.sequential._layer_call_argspecs (dict物件)
(6)
迭代重複(4)(5)步驟將所有的輸入layer都存到 keras.engine.sequential.self_tracked_trackables、keras.engine.training.Model.layers,並將各自__call_ 的參數規格存入 keras.engine.sequential._layer_call_argspecs中。
額外註明:
既然是 "layer stack",所以取出layer物件的方式就是使用 keras.engine.sequential.pop函式。
以上為建立Sequence物件keras主要會做的事項,做個紀錄。